﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace WMM.Tapioca.Utilities
{
    /// <summary>
    /// A MultiMap has multiple values and two keys. 
    /// With it we add multiple values to a single key(Tuple) in a Dictionary
    /// </summary>
    public class MultiMap<V>
    {
        Dictionary<Tuple<string, string, string, string>, HashSet<V>> _dictionary =
        new Dictionary<Tuple<string, string, string, string>, HashSet<V>>();

        /// <summary>
        /// This method is implemented with TryGetValue, and therefore
        /// usually has better performance than ContainsKey.
        /// </summary>
        public void Add(Tuple<string, string, string, string> key, V value)
        {
            HashSet<V> list;

            if (this._dictionary.TryGetValue(key, out list))
            {
                list.Add(value);
            }
            else
            {
                list = new HashSet<V>();
                list.Add(value);
                this._dictionary[key] = list;
            }
        }

        /// <summary>
        /// You will want to enumerate over Keys in your code.
        /// </summary>
        public IEnumerable<Tuple<string, string, string, string>> Keys
        {
            get
            {
                return this._dictionary.Keys;
            }
        }

        /// <summary>
        /// This provides natural and short syntax for accessing the MultiMap.
        /// Note that it returns an empty List if nothing exists.
        /// </summary>
        public HashSet<V> this[Tuple<string, string, string, string> key]
        {
            get
            {
                HashSet<V> list;

                if (!this._dictionary.TryGetValue(key, out list))
                {
                    list = new HashSet<V>();
                    this._dictionary[key] = list;
                }

                return list;
            }
            set
            {
                this._dictionary[key] = value;

                //HashSet<V> list;

                //if (!this._dictionary.TryGetValue(key, out list))
                //{
                //    list = new HashSet<V>();
                //    this._dictionary[key] = list;
                //}
            }
        }
    }
}
